#pragma once 
#include "def.h"
#define COL 9
#define ROW 9
#define SIZE 9
void FirstRow(int a[]){
	int i = 0,j = 0;
	srand((unsigned int)time(NULL));
	for(int i = 0;i < 9;i++){
		a[i] = rand()%9+1;
		j = 0;
		while(j<i){
			if(a[j] == a[i]){
				a[i] = rand()%9+1;
				j = 0;
			}
			else j++;
		}
	}
}

int RestRows(int a[9][9],int i,int j){
	if(i < COL&&j < ROW){
		int check[SIZE+1] = {0};//代表没有任何矛盾的元素
		//选出会产生矛盾的元素，并在check数组进行标记
		for(int x = 0;x < i;x++){
			check[a[x][j]] = 1;				
		}
		for(int y = 0;y < j;y++){
			check[a[i][y]] = 1;
		}
		int x1 = i/3*3;
		int y1 = j/3*3;
		for(int x = x1;x <= i;x++){
			if(x == i)
                for(int y = y1 ; y < j; y++)
					check[a[x][y]] = 1;
            else
                for(int y = y1 ; y < y1 + 3; y++)
                    check[a[x][y]] = 1;
		}
		
		int flag = 0;
		for(int k = 1;k <= SIZE&& flag == 0;k++){
			if(check[k] == 0){
				flag = 1;
				a[i][j] = k;
				if(j == SIZE-1&&i!= SIZE-1){
					if(RestRows(a,i+1,0) == 0){
						return 0;
					}
					else flag = 0;
				}
				else if(j!=SIZE-1){
					if(RestRows(a,i,j+1) == 0){
						return 0;
					}
					else flag = 0;
				}
				
			}
			
		}
		if(flag == 0){
				return 1;
			}
			
	}
	return 0;
}


void CreateSK(int a[9][9]){
	FirstRow(a[0]);
	RestRows(a,1,0);
}


void holes(int a[9][9]){
	srand((unsigned int)time(NULL));
	int N = rand()%7+3;
	for(int i = 0;i < N;i++){
		int x = rand()%9;
		int y = rand()%9;
		while(a[x][y] == 0){
			x = rand()%9;
			y = rand()%9;
		}
		a[x][y] = 0;
	}
}
void showSK(int a[9][9]){
	for(int i = 0;i < COL;i++){
		for(int j = 0;j < ROW;j++){
			if(a[i][j] == 0){
				printf("  ");
			}
			else printf("%d ",a[i][j]);
			if((j+1)%3==0){
				printf("|");
			}
		}
		printf("\n");
		if((i+1)%3==0){
			for(int i = 0;i < 10;i++){
				printf("- ");
			}
			printf("-");
			printf("\n");
		}
		
	}
	
}



void suduku2sat(int a[9][9],int emptynum){
	FILE* fp = fopen("suduku.cnf","w");
	printf("opened!\n");
	fprintf(fp,"p cnf %d %d\n",729,8829 + 81 - emptynum);
for (int i = 0; i < 9; ++i) {
    for (int j = 0; j < 9; ++j) {
      if (a[i][j] != 0) {
      	fprintf(fp,"%d 0\n",(i + 1) * 100 + (j + 1) * 10 + a[i][j]);
      }
    }
  }
  	for (int i = 1; i <= 9; ++i) {
    for (int j = 1; j <= 9; ++j) {
      for (int z = 1; z <= 9; ++z) {
        fprintf(fp,"%d ",i * 100 + j * 10 + z);
      }
      fprintf(fp,"0\n");
    }
  }
  	for (int z = 1; z <= 9; ++z) {
    for (int j = 1; j <= 9; ++j) {
      for (int i = 1; i <= 8; ++i) {
        for (int k = i + 1; k <= 9; ++k) {
        	fprintf(fp,"%d %d 0\n",0 - (i * 100 + j * 10 + z), 0 - (k * 100 + j * 10 + z) );
        }
      }
    }
  }
  	  for (int z = 1; z <= 9; ++z) {
    for (int i = 1; i <= 9; ++i) {
      for (int j = 1; j <= 8; ++j) {
        for (int k = j + 1; k <= 9; ++k) {
        	fprintf(fp,"%d %d 0\n",0 - (i * 100 + j * 10 + z), 0 - (i * 100 + k * 10 + z) );

        }
      }
    }
  }
     for (int z = 1; z <= 9; ++z) {
    for (int i = 0; i <= 2; ++i) {
      for (int j = 0; j <= 2; ++j) {
        for (int x = 1; x <= 3; ++x) {
          for (int y = 1; y <= 3; ++y) {
            for (int k = 1; k <= 3; ++k) {
              for (int l = 1; l <= 3; ++l) {
                if (x == k or y == l) {
                  continue;
                } else {
                	fprintf(fp,"%d %d 0\n",0 - (k * 100 + l * 10 + z), 0 - (x * 100 + y * 10 + z));
                }
              }
            }
          }
        }
      }
    }
  }
  fclose(fp);
}

void checka(int a[9][9]) {
	for (int i = 0; i < 9; i++) {
		for (int j = 0; j < 9; j++) {
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}
}
void SKplay(int a[9][9]){
		int i = 0,j = 0;
		int x = -1,y = -1;
		int num = 0;
		showSK(a);
		char filename[50] = "F:\\CS\\C++\\mySuduku\\suduku\\suduku.cnf";
		
		for (i = 0; i < 9; i++) {
			for (j = 0; j < 9; j++) {
				if ((a[i][j] == 0) && (num == 0)) {
					x = i;
					y = j;
					num++;
				}
				else if (a[i][j] == 0) {
					num++;
				}
			}
		}
		printf("there is %d holes in this suduku puzzle\n",num);
		suduku2sat(a, num);
		LinkClause C = init(filename);
		bool* result = new bool[2000];
		for (int i = 0; i < 2000; i++) {
			result[i] = true;
		}
		printf("ready to play!\n");
		AdvancedDPLL(C, result);
		printf("AdvancedDPLL successful!\n");
		while(num){
			int rep = 0;
			for (i = 0; i < 9; i++) {
				for (j = 0; j < 9; j++) {
					if (a[i][j] == 0&&rep == 0) {
						x = i;
						y = j;
						rep = 1;
					}
					
				}
			}
				printf("please input the number for (%d,%d)\n",x+1,y+1);
				scanf("%d",&a[x][y]);
				if(result[(x+1)*100+(y+1)*10+a[x][y]-1] == true) {
					printf("you are so brilliant!\ntry next one\n");
					showSK(a);
					num--;
					printf("%d holes left\n", num);
				}
				else{
					printf("sorry you are wrong!\n");
					a[x][y] = 0;
				}
				
				
		}
		printf("you did it!!!!!!!!!!!!!!!!\nSUDUKU_MASTER!!!!!!!!!\n");
		delete[] result;
		
}
void play(){
	int a[9][9] = {0};
	CreateSK(a);
	holes(a);
	SKplay(a);
}

